# -*- coding: utf-8 -*-    
# V1.00.01

import datetime    
import time    
import logging  
from enum import Enum  
import os  
import re 
import sys  

IngotDictionary = {  
    "Iron":             [0x1BF2, 0x0000],  
    "Dull Copper":      [0x1BF2, 0x0973],  
    "Shadow Copper":    [0x1BF2, 0x0966],  
    "Copper":           [0x1BF2, 0x096D],  
    "Bronze":           [0x1BF2, 0x0972],  
    "Golden":           [0x1BF2, 0x0973],  
    "Agapite":          [0x1BF2, 0x0979],  
    "Verite":           [0x1BF2, 0x089F],  
    "Valorite":         [0x1BF2, 0x08AB]  
}  

TongsMenuMap = {  
    # Ringmail类  
    'ringmail gloves'    : [1,  2,  0x13eb],    # 环甲手套  
    'ringmail leggings'  : [1,  9,  0x13f0],    # 环甲护腿  
    'ringmail sleeves'   : [1,  16, 0x13ee],    # 环甲袖子  
    'ringmail tunic'     : [1,  23, 0x13ec],    # 环甲上衣  
  
    # Chainmail类  
    'chainmail coif'     : [8,  2,  0x13bb],    # 链甲头巾  
    'chainmail leggings' : [8,  9,  0x13be],    # 链甲护腿  
    'chainmail tunic'    : [8,  16, 0x13bf],    # 链甲上衣  
  
    # Platemail类  
    'platemail arms'     : [15, 2,  0x1410],    # 板甲护臂  
    'platemail gloves'   : [15, 9,  0x1414],    # 板甲手套  
    'platemail gorget'   : [15, 16, 0x1413],    # 板甲喉甲  
    'platemail legs'     : [15, 23, 0x1411],    # 板甲护腿  
    'platemail tunic'    : [15, 30, 0x1415],    # 板甲上衣  
    'female plate'       : [15, 37, 0x1c04],    # 女式板甲  
  
    # Helmets类  
    'bascinet'           : [22, 2,  0x140c],    # 盆盔  
    'close helmet'       : [22, 9,  0x1408],    # 封闭式头盔  
    'helmet'             : [22, 16, 0x140a],    # 头盔  
    'norse helm'         : [22, 23, 0x140e],    # 诺斯头盔  
    'plate helm'         : [22, 30, 0x1412],    # 板甲头盔  
  
    # Shields类  
    'buckler'            : [29, 2,  0x1b73],    # 小圆盾  
    'bronze shield'      : [29, 9,  0x1b72],    # 青铜盾  
    'heater shield'      : [29, 16, 0x1b76],    # 加热盾  
    'metal shield'       : [29, 23, 0x1b7b],    # 金属盾  
    'metal kite shield'  : [29, 30, 0x1b74],    # 金属风筝盾  
    'tear kite shield'   : [29, 37, 0x1b79],    # 撕裂风筝盾  
  
    # Bladed类武器  
    'broadsword'         : [36, 9,  0xf5e],     # 宽剑  
    'cutlass'            : [36, 23, 0x1441],    # 短剑  
    'dagger'             : [36, 30, 0xf52],     # 匕首  
    'katana'             : [36, 37, 0x13ff],    # 日本刀（武士刀）  
    'kryss'              : [36, 44, 0x1401],    # 柯里斯剑（一种北欧短剑）  
    'longsword'          : [36, 51, 0xf61],     # 长剑  
    'scimitar'           : [36, 58, 0x13b6],    # 弯刀  
    'viking sword'       : [36, 65, 0x13b9],    # 维京剑  
  
    # Axes类武器  
    'large battle axe'   : [43, 30, 0x13fb],    # 大战斧  
    'double axe'         : [43, 16, 0xf4b],     # 双斧  
    "executioner's axe"  : [43, 23, 0xf45],     # 刽子手斧  
    'battle axe'         : [43, 9,  0xf47],     # 战斧  
    'two handed axe'     : [43, 37, 0x1443],    # 双手斧  
    'war axe'            : [43, 44, 0x13b0],    # 战争斧  
    'axe'                : [43, 2,  0xf49],     # 斧子  
  
    # Polearms类武器  
    'bardiche'           : [50, 2,  0xf4d],     # 长柄战斧  
    'halberd'            : [50, 23, 0x143e],    # 长柄斧枪  
    'short spear'        : [50, 44, 0x1403],    # 短矛  
    'spear'              : [50, 58, 0xf62],     # 长矛  
    'war fork'           : [50, 65, 0x1405],    # 战叉  
  
    # Bashing类武器  
    'war mace'           : [57, 30, 0x1407],    # 战争锤  
    'hammer pick'        : [57, 2,  0x143d],    # 锤镐  
    'mace'               : [57, 9,  0xf5c],     # 锤  
    'maul'               : [57, 16, 0x143b],    # 战锤（大锤）  
    'war hammer'         : [57, 37, 0x1439],    # 战争之锤  
  
    # ... 可以继续添加其他装备及其注释 ...  
}

class Color:
    def __init__(self):
        Color.Error = 33    # 红色
        Color.Warning = 55  # 黄色
        Color.Note = 88     # 绿色

class OrderBookClass:  
    def __init__(self): 
        self.ItemID = None 
        self.Serial = None  
        self.Name: str = None  
        self.DeedsInBook = None  
        self.Weight = None  


class OrderClass:  
    def __init__(self):  
        self.ItemName: str = None   
        self.ItemID = None 
        self.Serial = None
        self.IsExceptional = False 
        self.IsSmall = True   
        self.AmountToMake = None    
        self.CompletedQuantity = None
        self.PrimaryMenu = None
        self.SecondaryMenu = None

    def PrintDetails(self):  
        print(f"Item Name: {self.ItemName}")  
        print(f"Item ID: {self.ItemID}")   
        print(f"Is Small: {self.IsSmall}")    
        print(f"Is Exceptional: {self.IsExceptional}")    
        print(f"Amount To Make: {self.AmountToMake}")    
        print(f"Completed Quantity: {self.CompletedQuantity}")    
        print(f"Primary Menu: {self.PrimaryMenu}")    
        print(f"Secondary Menu: {self.SecondaryMenu}")  

class MyItemClass:  
    def __init__(self):  
        self.ItemName = None  
        self.Serial = None
        self.IsExceptional = False  
        # 你可以根据需要添加更多属性  

class OrderItemClass:  
    def __init__(self):  
        self.Type = None  # Item type  
        self.Item = None  # Item name 
        self.Quality = None  # Item quality level
        self.Material = None # Material of the item
        self.CompletedAmount = 0  # Completed quantity of the item  
        self.Amount = 0  # Total ordered quantity of the item
        self.PreviousPage = False # Previous page existence
        self.NextPage = False # Next page existence
        self.DropAction = None # Action to perform on item drop
    def __str__(self):  
        return f"OrderItem(Type={self.Type}, Item={self.Item}, Quality={self.Quality}, Material={self.Material}, CompletedAmount={self.CompletedAmount}, Amount={self.Amount}, PreviousPage={self.PreviousPage}, NextPage={self.NextPage}, DropAction={self.DropAction})"  
  
def GetBagMatrix():  
    """  
    Obtain and return a matrix of items grouped by their Z-axis position.  
    """  
    # >> 进入函数: GetBagMatrix  
    print()
    print(">> Entering function: GetBagMatrix")  
  
    # Step 1: Set up an item filter to select specific items on the ground  
    print("1. Setting up item filter...")  
    filter = Items.Filter()  
    filter.Enabled = True  
    filter.OnGround = True  
    filter.Graphics.Add(0x0E76)  
    print("   - Filter enabled for on-ground items with graphic ID 0x0E76.")  
  
    # Step 2: Get a list of items that meet the criteria  
    print("2. Applying filter to obtain items that meet the criteria...")  
    bags = Items.ApplyFilter(filter)  
    print(f"   - Found {len(bags)} items that meet the criteria.")  
  
    # Step 3: Group items based on their Z-axis position  
    print("3. Grouping items based on their Z-axis position...")  
    groupedItems = {}  
    for index, bag in enumerate(bags, start=1):  
        z_value = bag.Position.Z  
        groupedItems.setdefault(z_value, []).append(bag)  
        # Note: Usually, we don't print details of each bag here due to potential large output  
    print("   - Grouping completed.")  
  
    # Step 4: Sort and construct the item matrix  
    print("4. Sorting and constructing the item matrix...")  
    bagMatrix = [group for _, group in sorted(groupedItems.items())]  
    print("   - Item matrix constructed.")  
  
    # Print details of the bagMatrix after it is successfully generated  
    print("Details of the item matrix:")  
    for index, group in enumerate(bagMatrix, start=1):  
        print(f"   {index}. Z-axis position: {group[0].Position.Z if group else 'None'}, Number of items: {len(group)}")  
  
    # << 退出函数: GetBagMatrix  
    print("<< Exiting function: GetBagMatrix")  
  
    # Return the constructed item matrix  
    return bagMatrix


def TakePendingOrderFrom(orderBook):  
    """  
    Obtain and return the string list from the order book gump.  
    """  
    OrderBookGumpID = 0x54F555DF  
  
    # >> 进入函数: TakePendingOrderFrom  
    print()  
    print(">> Entering function: TakePendingOrderFrom")  
  
    # Step 1: Use the order book item  
    print("1. Using the order book item...")  
    Items.UseItem(orderBook.Serial)  
  
    # Step 2: Wait for the order book gump to appear  
    print("2. Waiting for the order book gump to appear...")  
    Gumps.WaitForGump(OrderBookGumpID, 10000)  
  
    # Step 3: Get the line list from the last gump  
    print("3. Getting the line list from the last gump...")  
    gumpStringList = Gumps.LastGumpGetLineList()  
  
    # Step 4: Check for unfinished orders  
    print("4. Checking for unfinished orders...")  
    has_unfinished_order = False  
    for line in gumpStringList:  
        if '/' in line:  
            parts = line.split('/')  
            if parts[0].strip() != parts[1].strip():  
                has_unfinished_order = True  
                break  
  
    # Step 5: Check for 'Next page' if no unfinished orders  
    print("5. Checking for 'Next page' if no unfinished orders...")  
    if not has_unfinished_order:  
        if 'Next page' in gumpStringList:  
            print("   - Found 'Next page'. Page flipping needed.")  
            # Simulate clicking the 'Next page' button (implementation required)  
            # Gumps.ClickGumpButton(OrderBookGumpID, "Next page")  
            # Recursive call or additional handling for subsequent pages may be needed  
        else:  
            print("   - All orders completed. This is the last page.")  
    else:  
        print("   - Unfinished orders exist.")  
  
    # Step 6: Wait before returning  
    print("6. Waiting before returning the gump string list...")  
    time.sleep(1)  
  
    # << 退出函数: TakePendingOrderFrom  
    print("<< Exiting function: TakePendingOrderFrom")  
  

def 检测系统存盘():
    pass

# Refill iron ingots from a specified container to the backpack  
# Parameters:  
# ingotsName: Name of the iron ingots to refill  
# threshold: Start refilling when the number of iron ingots is below this value  
# requiredAmount: Amount of iron ingots to take from the restock container each time  
# restockContainer: The container from which to restock the iron ingots  
# Returns:   
#   None - An error occurred during the refill process
#   Positive integer - The final count of ingots in the backpack after a successful refill (this is not explicitly returned in the current code) 
def RefillIronIngots(ingotsName, threshold, requiredAmount, restockContainer):  
    # >> 进入函数: RefillIronIngots  
    print()  
    print(f">> Refilling {ingotsName} ingots...")  
  
    # Step 1: Find all matching items in the backpack  
    print("1. Finding all matching ingots in the backpack...")  
    currentIngots = Items.FindAllByID(IngotDictionary[ingotsName][0], IngotDictionary[ingotsName][1], Player.Backpack.Serial, 0)  
    currentIngotsCount = sum(ingot.Amount for ingot in currentIngots) if currentIngots else 0  
    print(f"   - Current {ingotsName} ingots count in the backpack: {currentIngotsCount}")  
  
    # Step 2: Check if refilling is needed  
    if currentIngotsCount < threshold:  
        print(f"2. {ingotsName} ingots count is below the threshold, starting to refill...")  
  
        # Step 3: Use the restock container  
        print("3. Using the restock container...")  
        Items.UseItem(restockContainer)  
        print("   - Restock container used.")  
  
        # Step 4: Wait for 1 second  
        print("4. Waiting for 1 second...")  
        time.sleep(1)  
  
        # Step 5: Find iron ingots in the restock container  
        print("5. Finding iron ingots in the restock container...")  
        ironIngots = Items.FindByID(IngotDictionary[ingotsName][0], IngotDictionary[ingotsName][1], restockContainer, 0)  
  
        if ironIngots and ironIngots.Amount > 0:  
            # Step 6: Calculate the amount to move  
            amountToMove = ironIngots.Amount if ironIngots.Amount < requiredAmount else requiredAmount  
            print(f"6. Moving {amountToMove} {ingotsName} ingots from the restock container to the backpack...")  
  
            # Step 7: Move ingots to the backpack  
            Items.Move(ironIngots, Player.Backpack.Serial, amountToMove)  
  
            # Step 8: Wait for 1 second  
            print("7. Waiting for 1 second...")  
            time.sleep(1)  
  
            # Step 9: Check the final ingots count in the backpack  
            print("9. Checking the final ingots count in the backpack...")  
            finalIngots = Items.FindAllByID(IngotDictionary[ingotsName][0], IngotDictionary[ingotsName][1], Player.Backpack.Serial, 0)  
            finalIngotsCount = sum(ingot.Amount for ingot in finalIngots) if finalIngots else 0  
  
            if finalIngotsCount >= amountToMove:  
                print(f">> Ingots refill process completed successfully. Current count: {finalIngotsCount}")  
                return finalIngotsCount  
            else:  
                print(">> Error: Ingots count after restocking is lower than expected.")  
                return None  
        else:  
            print(">> Not enough ingots in the restock container.")  
            return None  
    else:  
        print(">> No need to refill, current ingots count is above the threshold.")  
        return currentIngotsCount  


# 补充修补工具
# 数量: 修补工具小于此值时开始补充
# 返回值:
#    0 - 无需补充  
#    1 - 成功触发了补充流程（但不一定补充成功，取决于后续操作）  
#   -1 - 背包中没有修补工具，无法补充修补工具
def ReplenishTinkerTool(quantity):  
    result  = 0

    currentTinkerToolCount = Items.BackpackCount(TinkerToolItemID, -1)
    # Misc.SendMessage(f"Found {currentTinkerToolCount} tinker's tools...", 55)  

    if currentTinkerToolCount == 0:    
        Misc.SendMessage(f"No Tinker's Tool found in the backpack...", 33)  
        time.sleep(0.5) 
        result = -1
    elif currentTinkerToolCount < quantity: 
        Misc.SendMessage(f"Replenishing Tinker's tool...", 55)  

        TinkerTool = Items.FindByID(TinkerToolItemID, -1, Player.Backpack.Serial, True) 

        Items.UseItem(TinkerTool.Serial)
        Gumps.WaitForGump(TinkerToolGmupID, 10000)
        Gumps.SendAction(TinkerToolGmupID, 8)
        Gumps.WaitForGump(TinkerToolGmupID, 10000)
        Gumps.SendAction(TinkerToolGmupID, 23)
        Gumps.WaitForGump(TinkerToolGmupID, 10000)
        Gumps.SendAction(TinkerToolGmupID, 0)

        result = 1

    return result

# 补充火钳
# 数量：火钳工具数量小于此值时开始补充
# 返回值:
#    0 - 无需补充  
#    1 - 成功执行了补充流程（但不一定补充成功，取决于后续操作）  
def ReplenishTools(quantity): 
    result = 0

    currentTongsCount = Items.BackpackCount(TongsItemID, -1)
    #Misc.SendMessage(f"Found {currentTongsCount} 个火钳工具...", 55) 
     
    if currentTongsCount < quantity:
        Misc.SendMessage("Replenishing Tongs...", 55) 

        TinkerTool = Items.FindByID(TinkerToolItemID, -1, Player.Backpack.Serial, True) 
        
        Items.UseItem(TinkerTool.Serial)
        Gumps.WaitForGump(TinkerToolGmupID, 10000)
        Gumps.SendAction(TinkerToolGmupID, 8)
        Gumps.WaitForGump(TinkerToolGmupID, 10000)
        Gumps.SendAction(TinkerToolGmupID, 86)
        Gumps.WaitForGump(TinkerToolGmupID, 10000)
        Gumps.SendAction(TinkerToolGmupID, 0)

        #time.sleep(0.5)
        result = 1

    return result


def GetOrderAtrributes(orderSerial):

    print("Getting order atrributes...")
    # 获取订单属性
    orderPropertyList  = Items.GetPropStringList(orderSerial)
    time.sleep(1)
    order = OrderClass()
    order.Serial = orderSerial
    #for propString in orderPropertyList:  
    #    print(propString)

    # 遍历订单属性列表  
    for propString in orderPropertyList:  

        # 检查订单是否是小订单
        if "small bulk order" in propString:  
            order.IsSmall = True

        # 检查订单是否是大订单
        if "large bulk order" in propString: 
            order.IsSmall = False

        # 检查订单是否是精品  
        if "All items must be exceptional." in propString:  
            order.IsExceptional = True  

        # 提取订单要求的总数  
        if propString.startswith("amount to make:"):  
            order.AmountToMake = int(propString.split(": ")[1])  
            
        # 提取订单需要的物品和已经完成的数量（假设最后一行包含这些信息）  
        if propString == orderPropertyList[len(orderPropertyList)-1]:  
            item_parts = propString.split(": ")  
            order.ItemName = item_parts[0].strip()  
            order.CompletedQuantity = int(item_parts[1]) if len(item_parts) > 1 else None

    # 提取订单物品在火钳工具菜单中的选项
    if order.ItemName in TongsMenuMap:  
        order.PrimaryMenu, order.SecondaryMenu, order.ItemID = TongsMenuMap[order.ItemName]
    else:
        print(f"Item not found in the mapping table: {order.ItemName}")  
        return None
    
    return order

# 获取订单书中的订单数量
def GetOrderBookAtrributes(orderBookSerial):  
    # 获取订单属性  
    orderPropertyList = Items.GetPropStringList(orderBookSerial)  
      
    # 遍历属性列表，寻找"Deeds In Book"  
    for propString in orderPropertyList:  
        #print(propString)
        if propString.startswith("Deeds in book:"):  
            # 分割字符串以获取数字  
            deeds_count = propString.split(":")[1].strip()  
            # 将字符串转换为整数并返回  
            return int(deeds_count)  
  
    # 如果没有找到"Deeds In Book"，则返回None或抛出异常  
    return None  

def CraftItem(order):  
    # Send message to start crafting  
    print()  
    print(f">> Crafting {order.ItemName}")  
  
    # Cancel current target selection  
    print(f"1. Colsing gump: {TinkerToolGmupID}...")  
    Gumps.CloseGump(TinkerToolGmupID)  

    print("2. Cancelling target selection...")  
    Target.Cancel()  
  
    # Find and use tongs tool in the player's backpack  
    print("3. Searching for tongs in backpack...")  
    tongs = Items.FindByID(TongsItemID, -1, Player.Backpack.Serial, True)  
    if tongs is None:  
        print("4. Tongs not found, aborting crafting.")  
        return False  
    
    print(f"4. Using tongs: {tongs.Serial}...")  
    Items.UseItem(tongs.Serial)  
  
    # Wait for tinker tool gump and interact  
    print(f"5. Waiting for tinker tool gump: {TinkerToolGmupID}...")  
    if not Gumps.WaitForGump(TinkerToolGmupID, 10000):  
        print("6. Failed to detect tinker tool gump , aborting.")  
        return False  
  
    # Send primary menu action  
    print(f"6. Sending primary menu action: {order.PrimaryMenu}...")  
    Gumps.SendAction(TinkerToolGmupID, order.PrimaryMenu)  
  
    # Wait for the next gump  
    print(f"7. Waiting for tinker tool gump: {TinkerToolGmupID}...")  
    if not Gumps.WaitForGump(TinkerToolGmupID, 10000):  
        print("8. Failed to detect tinker tool gump , aborting.")  
        return False  
  
    # Send secondary menu action  
    print(f"8. Sending secondary menu action: {order.SecondaryMenu}...")  
    Gumps.SendAction(TinkerToolGmupID, order.SecondaryMenu)  
  
    # Wait for the final tinker tool gump  
    print(f"9. Waiting for tinker tool gump: {TinkerToolGmupID}...")  
    if not Gumps.WaitForGump(TinkerToolGmupID, 10000):  
        print("10. Failed to detect tinker tool gump , aborting.")  
        return False  
  
    # Cancel target selection and finish  
    print(f"10. Colsing gump: {TinkerToolGmupID}...")  
    Gumps.CloseGump(TinkerToolGmupID)  

    print("11. Cancelling target selection...")  
    Target.Cancel()  
  
    # Pause for system processing  
    print("12. Pausing for system processing...")  
    time.sleep(1)  
  
    # Send message indicating crafting is complete  
    print(">> Crafting completed successfully.")  
    return True

def SmeltItem(itemSerial):  
    # Send message to start smelting  
    print()  
    print(f">> Smelting item: {itemSerial}")  
  
    # Cancel current target selection  
    print(f"1. Closing gump: {TinkerToolGmupID}...")  
    Gumps.CloseGump(TinkerToolGmupID)  
    
    print("2. Cancelling target selection...")  
    Target.Cancel()
  
    # Find and use tongs tool  
    print("3. Searching for tongs in backpack...")  
    tongs = Items.FindByID(TongsItemID, -1, Player.Backpack.Serial, True) 
    if tongs is None:  
        print("4. Tongs not found, aborting crafting.")  
        return False   
    
    print(f"4. Using tongs item with serial: {tongs.Serial}...")  
    Items.UseItem(tongs.Serial)  
  
    # Wait for tinker tool gump and interact  
    print(f"5. Waiting for tinker tool gump: {TinkerToolGmupID}...")  
    if not Gumps.WaitForGump(TinkerToolGmupID, 10000):  
        print("6. Failed to detect tinker tool gump, aborting.")  
        return False  

    print("6. Sening smelt action: 14...")  
    Gumps.SendAction(TinkerToolGmupID, 14)  
  
    # Wait for target and select item to smelt  
    print("6. Waiting for target selection...")  
    if not Target.WaitForTarget(10000, False):  
        print("7. Failed to wait for target")  
        return False  

    print("8. Item targeted for smelting...")  
    Target.TargetExecute(itemSerial)  
  
    # Wait for tinker tool gump again and send completion action  
    print(f"9. Waiting for tinker tool gump: {TinkerToolGmupID}...")  
    if not Gumps.WaitForGump(TinkerToolGmupID, 10000):  
        print("10. Failed to detect tinker tool gump, aborting.")   
        return False  
  
    # Cancel target selection  
    print(f"11. Closing gump: {TinkerToolGmupID}...")  
    Gumps.CloseGump(TinkerToolGmupID)  
  
    print("12. Cancelling target selection...")  
    Target.Cancel()  

    # Pause for system processing  
    print("13. System processing pause complete.")  
    time.sleep(1)  
  
    # Send message indicating smelting is complete  
    print(">> Smelting completed successfully.")  
    return True

# 函数名称：RefillItem  
# 函数功能：对指定物品进行充单操作  
# 参数说明：  
#   craftItem：需要充单的物品对象，包含物品名称等信息  
#   orderSerial：订单物品的序列号  
#   itemSerial：需要充单的物品的序列号  
#   orderGumpId：订单界面的标识符  
# 返回值：无（函数主要执行操作，不直接返回数据）  
# 作者：于爽  
# 日期：2024-06-19  
def RefillItem(orderSerial, itemToMake, orderGumpId):  
    # 发送充单开始消息  
    print()  
    print(f">> Starting refill for item: {itemToMake.ItemName}")  
  
    # Cancel current target selection  
    print(f"1. Closing gump: 0X{TinkerToolGmupID:08X}...")  
    Gumps.CloseGump(TinkerToolGmupID)  
    
    print("2. Cancelling target selection...")  
    Target.Cancel()  
  
    # 使用订单物品  
    print(f"3. Using order item with serial: 0X{orderSerial:08X}")  
    Items.UseItem(orderSerial)  
  
    # Wait for order gump and interact  
    print(f"4. Waiting for order gump: 0X{orderGumpId:08X}...")  
    if not Gumps.WaitForGump(orderGumpId, 10000):  
        print("5. Failed to detect tinker tool gump, aborting.")  
        return False  
  
    # 选择充单操作  
    print("5. Sending refill action: 2...")  
    Gumps.SendAction(orderGumpId, 2)  
  
    # 等待目标选择界面  
    print("6. Waiting for target selection...")  
    if not Target.WaitForTarget(10000, False):  
        print("7. Failed to detect tinker tool gump, aborting.")  
        return False  
  
    # 执行充单操作  
    print(f"7. Targeting item to refill: 0X{itemToMake.Serial:08X}")  
    Target.TargetExecute(itemToMake.Serial)  
  
    # 再次等待订单界面更新  
    print(f"8. Waiting for order gump update: 0X{orderGumpId:08X}...")  
    if not Gumps.WaitForGump(orderGumpId, 10000):  
        print("9. Failed to detect tinker tool gump, aborting.")  
        return False  
  
    # 关闭订单界面  
    print(f"10. Closing gump: 0X{orderGumpId}")  
    Gumps.CloseGump(orderGumpId)  
  
    # 取消目标选择  
    print("11. Cancelling target selection...")  
    Target.Cancel()  

    # 暂停1秒钟，以便给系统足够的时间处理动作  
    print("12. Pausing for system processing...")  
    time.sleep(1)  
  
    # 发送充单完成消息  
    print(">> Refill completed successfully.")  
    return True

# 函数名称：TakeOrderFromBook  
# 函数功能：从指定的订单书中取出第一个订单  
# 参数说明：  
#   orderSourceSerial：订单书的序列号  
#   orderBookGumpID：订单书界面的标识符  
# 返回值：无（函数主要执行操作，不直接返回数据）  
# 作者：于爽
# 日期：2024-06-19
def TakeOrderFromBook(orderBook, action):  
    # 进入函数时打印开始信息  
    print("Taking order from book...")  
    print(action)
    # 打开订单书  
    Items.UseItem(orderBook.Serial)  
    time.sleep(1)
    Gumps.WaitForGump(OrderBookGumpID, 10000)  
    Gumps.SendAction(OrderBookGumpID, action)  
    Gumps.WaitForGump(OrderBookGumpID, 10000)    
    Gumps.SendAction(OrderBookGumpID, 0)  
    print("Order taken.")  

def PutOrderInBook(orderSerial, orderBookSerial):  
    Items.Move(orderSerial, orderBookSerial, 1)  
    Gumps.WaitForGump(OrderBookGumpID, 10000)  
    Gumps.SendAction(OrderBookGumpID, 0)  
    time.sleep(1)


def GetPendingOrderBookInBackpack():  
    pendingOrderBook = OrderBookClass()
    print()
    print(">> Entering function: Get pending order book in backpack.")

    print("1. Searching for a pending order book... ")  
    orderBookItem = Items.FindByID(OrderBookItemID, -1, Player.Backpack.Serial)  
    if orderBookItem is None:  
        print("2. No pending orderbook was found in backpack.")  

        print("3. Searching for a pending order book in bag matrix.")  
        for element in BagMatrix[0]:    
            Items.Message(element, 33, "!")  
            Items.Message(element, 33, "!")  
            Items.Message(element, 33, "!")  

            print(f"Using bag {element.Serial}.")  
            Items.UseItem(element.Serial)

            print("Waiting for one second")   
            time.sleep(1)  

            orderBookItem = Items.FindByID(OrderBookItemID, -1, element.Serial)  
            if orderBookItem is not None:  
                Items.Message(element, 33, "!!!")  
                Items.Message(element, 33, "!!!")  
                Items.Message(element, 33, "!!!")  

                print(f"4. A pending order book 0x{orderBookItem.Serial:08X} was found in bag matrix.")

                print("Moving the pending order book to the backpack.")   
                Items.Move(orderBookItem.Serial, Player.Backpack.Serial, 1) 

                print("Waiting for one second")   
                time.sleep(1)  

                print("<< Exiting function.")
                return None
                        
        while True:
            print("5. No pending orderbook was found in bag matrix.")  
            time.sleep(1)
    else:    
        print(f"2. A pending order book was found in backpack: 0x{orderBookItem.Serial:08X}.")
        pendingOrderBook.Name = orderBookItem.Name
        pendingOrderBook.DeedsInBook = int(Items.GetPropValue(orderBookItem, "Deeds in book"))
        pendingOrderBook.Weight = int(Items.GetPropValue(orderBookItem, "Weight"))
        pendingOrderBook.Serial = orderBookItem.Serial
        pendingOrderBook.ItemID = orderBookItem.ItemID

        print(f"   Order book name: {orderBookItem.Name}")  
        print(f"   Deeds in book: {pendingOrderBook.DeedsInBook}")  
        print(f"   Weight: {pendingOrderBook.Weight}")  
        print(f"   Serial: 0x{pendingOrderBook.Serial:08X}")  
        print(f"   ItemID: 0x{pendingOrderBook.ItemID:04X}")  

        print("<< Exiting function.")

        return pendingOrderBook
        

def GetPendingOrderInBackpack(pendingOrderBook):  
    print()
    print(">> Entering function: Get pending order in backpack.")  
  
    print("1. Searching for a pending order in the backpack... ")  
    pendingOrder = Items.FindByID(OrderItemID, -1, Player.Backpack.Serial)  
    if pendingOrder is None:  
        print("2. No pending order was found in backpack.")  
  
        print("3. Attempting to find a pending order in the order book.")  
        pendingOrder = TakePendingOrderFrom(pendingOrderBook)  
  
        print("<< Exiting function.")  
        return None  
    else:  
        print(f"2. A pending order was found in backpack: 0x{order.Serial:08X}.")  
        pendingOrderProperty = GetOrderAtrributes(order.Serial)  
        if pendingOrderProperty is None:  
            print("3. Unable to get order attributes.")  
            print("<< Exiting function.")  
            return None  
        else:  
            print("4. Order attributes were retrieved successfully.")  
            for name, value in vars(pendingOrderProperty).items():  
                print(f"   {name}: {value}")  
  
            print("<< Exiting function.")  
            return pendingOrderProperty
        
def FindItemToMakeInBackpack(itemID):

    print("Searching for item to make as per order requirements.")
    myItem = MyItemClass()

    # 先处理背包中的订单
    reslut = Items.FindByID(itemID, -1, Player.Backpack.Serial)

    if reslut is None:
        return None
    
    myItem.Serial = reslut.Serial

    itemList = Items.GetPropStringList(reslut.Serial)

    for prop in itemList:  
        
        if myItem.ItemName is None:  
            # 提取物品名称
            myItem.ItemName = prop.strip()

        if "exceptional" in prop:    
            myItem.IsExceptional = True 
            # 如果"exceptional"出现在物品名称中，需要将其从名称中移除    
            if "exceptional" in prop.lower():  
                myItem.ItemName = myItem.ItemName.replace("exceptional", "").strip()  
                break            
    return myItem 

def ProcessOrders():  

    # 补充铁锭
    #if RefillIronIngots(50, 300) != 0:
    #    return
    
    # 补充修补工具 
    if ReplenishTinkerTool(2) != 0:
        return
    
    # 补充火钳工具
    if ReplenishTools(2) != 0:
        return

    # Searching for a pending order book in the backpack.
    PendingOrderBook = OrderBookClass()
    PendingOrderBook = GetPendingOrderBookInBackpack()
    if PendingOrderBook is None:
        return
    # 应该检查订单数是否已经完成，如果是一本未完成的订单，才继续向下执行
    # 如果订单数已经完成，放到第二层，然后从第一层拿一本订单数


    PendingOrder = OrderClass()
    PendingOrder = GetPendingOrderInBackpack(PendingOrderBook)
    if PendingOrder is None:
        return
        
    # 如果订单已经完成，放进订单书
    if PendingOrder.AmountToMake == PendingOrder.CompletedQuantity:
        # 将订单放进订单书
        print("Put the completed order into the order book...", 77) 
        PutOrderInBook(PendingOrder, PendingOrderBook)
        return
    else:
        print("11")

    # 在背包中寻找物品，制作、充单或熔毁
    ItemToMake = FindItemToMakeInBackpack(PendingOrder.ItemID)
    if ItemToMake is None:
        CraftItem(PendingOrder)
        return
    else:
        print(f"The item was found: {ItemToMake.Serial}")

    if ItemToMake.ItemName == PendingOrder.ItemName:
        if PendingOrder.IsExceptional == True and ItemToMake.IsExceptional == False:
            #熔毁
            SmeltItem(ItemToMake.Serial) 
        else:
            # 充单
            RefillItem(PendingOrder.Serial, ItemToMake, OrderGmupID) 
    else:
        print(ItemToMake.ItemName)
        print(PendingOrder.ItemName)
    time.sleep(1)  
    
# 交付订单的函数    
def 交付订单():    
    # 模拟订单交付逻辑    
    time.sleep(3)  # 模拟订单交付，延迟3秒    
  
# 整理订单的函数    
def 整理订单():    
    # 模拟订单整理逻辑    
    time.sleep(2)  # 模拟订单整理，延迟2秒    

BagMatrix = None  
OrderBook = None

RestockSerial           = 0x4AB0895F  # 存放铁锭的原料箱序列号

OrderGmupID             = 0x5AFBD742  # 订单GumpID：    1526454082
OrderBookGumpID         = 0x54F555DF  # 订单书GumpID：  1425364447
TinkerToolGmupID        = 0x38920ABD  # 修补工具GumpID： 949095101

OrderItemID             = 0x2258      # 订单ItemID
OrderBookItemID         = 0x2259
TinkerToolItemID        = 0x1EB8      # 修补工具ItemID
TongsItemID             = 0x0FBB      # 火钳工具ItemID
IronIngotItemID         = 0x1BF2      # 铁锭ItemID


def Run():
    global BagMatrix
    # Obtain a matrix of bags  
    if BagMatrix is None:
        BagMatrix = GetBagMatrix()

    # 计数器初始化  
    counter = 0  
    
    while True:  
        counter += 1  
        print()
        print(f"--- Loop {counter}")  
        
        当前时间 = datetime.datetime.now()  # 获取当前时间  
        小时 = 当前时间.hour  # 提取当前小时数  
        格式化时间 = 当前时间.strftime('%Y-%m-%d %H:%M')  # 格式化当前时间为字符串  
        
        # 根据时间判断应该执行的操作  
        if 15 <= 小时 < 24 or 0 <= 小时 < 15:  
            message = f"[{格式化时间}] Processing orders"  
            print(message)  
            ProcessOrders()  # 执行订单处理函数  
        elif 9 <= 小时 < 14:  
            message = f"[{格式化时间}] Delivering orders"  
            print(message)  
            交付订单()  # 执行订单交付函数  
        elif 14 <= 小时 < 15:  
            message = f"[{格式化时间}] Organizing orders"  
            print(message)  
            整理订单()  # 执行订单整理函数  
        else:  
            print(f"[{格式化时间}] Sleep 1 minute")  
            time.sleep(60)  # 休眠1分钟